package com.qianfeng.exam.service.impl;


import com.github.pagehelper.util.StringUtil;
import com.qianfeng.exam.cache.UserCache;
import com.qianfeng.exam.constants.ResultCode;
import com.qianfeng.exam.dto.UserDto;
import com.qianfeng.exam.event.UserCacheChangeEvent;
import com.qianfeng.exam.exceptions.AddDataException;
import com.qianfeng.exam.mapper.UserMapper;
import com.qianfeng.exam.pojo.Users;
import com.qianfeng.exam.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.Random;

@Service//声明是service
@Transactional//默认全部开启事务
public class UserServiceImpl implements IUserService {
    //mapper接口 映射文件
    @Autowired
    private UserMapper userMapper;
    //缓存对象 利用单例模式 在服务器启动时创建 ,在init初始化时,会查询数据到内存中,减少磁盘IO消耗
    @Autowired
    private UserCache userCache;
    @Autowired//用bean的容器,发送事件,用于修改缓存中数据后,更新缓存数据
    private ApplicationContext context;
    @Autowired//一个标识,该类加了Component注解
    private UserCacheChangeEvent event;


    public void register(UserDto user) {
        //因为注册时用户必须填入所有的数据,所以前置判断一下
        //如果传递的数据不完整,或是没有传,都不应执行后续代码
        //即使前端设置了必填,我们后端也要进行校验,因为前端数据可能会被篡改

        //1.判断数据是否符合我们预期 如果没有达到预期,直接抛异常给前端
        if (user == null||user.getUsername().isEmpty()){
            throw new AddDataException("用户名不能为空", ResultCode.USERNAME_IS_NULL);
        }
        //验证该用户名是否已经存在数据库中 需要先查询一次数据库,可以在缓存中查询
        Users obj = userCache.getObj(user.getUsername());
        if (obj != null){
            throw new AddDataException("用户名已经存在", ResultCode.USERNAME_EXIST);
        }
        //----此处应该验证密码格式是否正确,先忽略---
        if (user.getPassword().isEmpty()){
            throw new AddDataException("密码不能为空",ResultCode.PASSWORD_ISNULL_NOT_NORM);
        }
        if (!user.getRepeatPassword().equals(user.getPassword())){
            throw new AddDataException("两次密码不一致",ResultCode.PASSWORD_NOT_SAME);
        }

//        2.验证完传入的数据后 现在添加用户到数据库
//        在添加之前,需要对用户的密码进行加密
        if (!StringUtil.isEmpty(user.getPassword())) {
            String MD5 = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
            //转换为md5 值之后,进行加盐
            long timeMillis = System.currentTimeMillis();
            Random random = new Random();
            long result = timeMillis - random.nextInt(1000000000);
            String s = result + "";
            String salt = s.substring(random.nextInt(5), s.length() - 1);
            if (salt.length() > 10) {
                salt = salt.substring(salt.length() - 10);
            }
            String NewMD5 = MD5.substring(MD5.length() / 2, MD5.length() - 1);
            System.out.println(salt+"=============="+MD5);
            user.setPasswordsalt(salt);
            user.setPassword(salt+NewMD5);
        }
        userMapper.addUser(user);
        context.publishEvent(event);//发送事件
    }
}
